package ncorps.output;

import ncorps.commun.ConditionInitiale;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import static java.lang.Math.*;

public class ImageOut {

    private BufferedImage image;
    private String imageFilename;
    private String format;
    private int Max;
    private double SpeedEch;
    private int[] colorRef;
    private String RepImages;

    public void printi(String repimages, String imagefilename, String format, ConditionInitiale CI) throws IOException {
        this.RepImages = repimages;
        this.imageFilename = imagefilename;
        this.format = format;
        Max = 32;
        SpeedEch = 1;
        image = new BufferedImage(960, 600, BufferedImage.TYPE_INT_RGB);
        colorRef = CI.getColorRef();
        drawbody(CI.getGcoord(), CI.get_N());
        saveImage(imagefilename, format);
    }

    public void printi1(String repimages, String imagefilename, String format, double[][] gcoord, ConditionInitiale CI) throws IOException {
         this.RepImages = repimages;
        this.imageFilename = imagefilename;
        this.format = format;
        Max = 32;
        SpeedEch = 1;
        image = new BufferedImage(960, 600, BufferedImage.TYPE_INT_RGB);
        colorRef = CI.getColorRef();
        drawbody(gcoord, CI.get_N());
        saveImage(imagefilename, format);
    }

    private void drawbody(double[][] gcoord, int _N) {
        int x, y;


        double EchX = 960 / Max, EchY = 600 / Max;
        for (int n = 0; n < _N; n++) {
            int bodycolor = colorRef[n];
            x = (int) (EchX * gcoord[n][1]);
            y = (int) (EchY * gcoord[n][2]);

            if (inbounds(x, y, 960, 600)) {
                image.setRGB(x, y, bodycolor);
                drawspeed(x, y, n, gcoord);
            }
            if (inbounds(x + 1, y, 960, 600)) {
                image.setRGB(x + 1, y, bodycolor);
            }
            if (inbounds(x, y + 1, 960, 600)) {
                image.setRGB(x, y + 1, bodycolor);
            }
            if (inbounds(x - 1, y, 960, 600)) {
                image.setRGB(x - 1, y, bodycolor);
            }
            if (inbounds(x, y - 1, 960, 600)) {
                image.setRGB(x, y - 1, bodycolor);

            }


        }

    }

    private void drawspeed(int x, int y, int n, double[][] field) {
        double vx = field[n][3];
        double vy = field[n][4];
        if (inbounds(x + vx * SpeedEch, y + vy * SpeedEch, 960, 600)) {
            drawSegment(x, y, x + vx * SpeedEch, y + vy * SpeedEch, n);
            drawArrow(x, y, x + vx * SpeedEch, y + vy * SpeedEch, n);
        }
    }

    private void drawArrow(int x1, int y1, double x2, double y2, int n) {
        double x2a = 0, y2a = 0, x2b = 0, y2b = 0;
        double alpha = PI / 6;
        double dx = x1 - x2;
        double dy = y1 - y2;
        x2a = (dx * cos(alpha) - dy * sin(alpha)) / 4 + x2;
        y2a = (dx * sin(alpha) + dy * cos(alpha)) / 4 + y2;
        x2b = (dx * cos(-alpha) - dy * sin(-alpha)) / 4 + x2;
        y2b = (dx * sin(-alpha) + dy * cos(-alpha)) / 4 + y2;
        if (inbounds(x2a, y2a, 960, 600)) {
            drawSegment(x2, y2, x2a, y2a, n);
        }
        if (inbounds(x2b, y2b, 960, 600)) {
            drawSegment(x2, y2, x2b, y2b, n);
        }

    }

    void drawSegment(double x1, double y1, double x2, double y2, int n) {
        int arrowcolor = colorRef[n];
        int dx, dy, i, xinc, yinc, cumul, x, y;
        x = (int) x1;
        y = (int) y1;
        dx = (int) (x2 - x1);
        dy = (int) (y2 - y1);
        xinc = (dx > 0) ? 1 : -1;
        yinc = (dy > 0) ? 1 : -1;
        dx = abs(dx);
        dy = abs(dy);
        image.setRGB(x, y, arrowcolor);
        if (dx > dy) {
            cumul = dx / 2;
            for (i = 1; i <= dx; i++) {
                x += xinc;
                cumul += dy;
                if (cumul >= dx) {
                    cumul -= dx;
                    y += yinc;
                }
                image.setRGB(x, y, arrowcolor);
            }
        } else {
            cumul = dy / 2;
            for (i = 1; i <= dy; i++) {
                y += yinc;
                cumul += dx;
                if (cumul >= dy) {
                    cumul -= dy;
                    x += xinc;
                }
                image.setRGB(x, y, arrowcolor);
            }
        }
    }

    private boolean inbounds(double x, double y, int dimx, int dimy) {
        return (x > 0) && (y > 0) && (x < dimx) && (y < dimy);
    }

    private void saveImage(String imagefilename, String format) throws IOException {
//        File fic = new File(new File(".").getCanonicalPath() + "/IMG/" + imagefilename + "." + format);
        File fic = new File(RepImages + imagefilename + "." + format);
        ImageIO.write(image, format, fic);
    }
}












